#pragma once
#include <atomic>
#include <condition_variable>
#include <functional>
#include <list>
#include <memory>
#include <mutex>
#include <queue>
#include <string>
#include <thread>
#include <vector>
#include <pthread.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <unistd.h>
struct Task
{
    // 线程池上下文信息
    std::string thread_name;
    // 线程池任务
    std::function<void()> func;
};

class ThreadPool
{
   public:
    ThreadPool(int num_threads = std::thread::hardware_concurrency()) : stop_flag_(false)
    {
        for (int i = 0; i < num_threads; i++)
        {
            threads_.emplace_back([this]() {
                // pthread_setname_np(pthread_self(), "thread_name");
                
                while (true)
                {
                    Task task;
                    {
                        std::unique_lock<std::mutex> lock(mutex_);
                        condition_.wait(lock, [this]() { return stop_flag_ || !task_queue_.empty(); });
                        if (stop_flag_ && task_queue_.empty())
                        {
                            return;
                        }
                        task = std::move(task_queue_.front());
                        task_queue_.pop();
                    }
                    // prctl(PR_SET_NAME, task.thread_name.c_str());
                    pthread_setname_np(pthread_self(),task.thread_name.c_str());
                    task.func();
                }
            });
        }
    }
    // 提交任务到任务队列
    void submit(Task task)
    {
        std::unique_lock<std::mutex> lock(mutex_);
        task_queue_.push(std::move(task));
        condition_.notify_one();
    }

    void submit(std::function<void()> func, const std::string &thread_name)
    {
        Task task = {thread_name, std::move(func)};
        std::unique_lock<std::mutex> lock(mutex_);
        task_queue_.push(std::move(task));
        condition_.notify_one();
    }
    // 关闭线程池
    void stop()
    {
        {
            std::unique_lock<std::mutex> lock(mutex_);
            stop_flag_ = true;
        }
        condition_.notify_all();
        for (auto &thread : threads_)
        {
            thread.join();
        }
    }

   private:
    std::vector<std::thread> threads_;
    std::queue<Task> task_queue_;
    std::mutex mutex_;
    std::condition_variable condition_;
    bool stop_flag_;
};
